//
//  ServcePanelAirConditioner.swift
//  home
//
//  Created by Yun Zeng on 2019/9/16.
//  Copyright © 2019 Yun Zeng. All rights reserved.
//

import UIKit

class ServicePanelAirConditioner: ServicePanelBase {
    let contentWidth = 375
    let  contentHeight = 680
    let  contentYOffset = 25
    
    fileprivate var panelState: AirStatePanelView!
    lazy var panelStateRect = CGRect(x: (contentWidth - 174) / 2, y: contentYOffset + 57, width: 174, height: 174)
    lazy var panelStateOffRect = CGRect(x: (contentWidth - 174) / 2, y: contentYOffset + 98, width: 174, height: 174)
    
    fileprivate var panelTempCtrl: AirTemperatureControlPanel!
    lazy var panelTempCtrlRect = CGRect(x: (contentWidth - 288) / 2, y: contentYOffset + 0, width: 288, height: 288)
    
    fileprivate var panelCtrl: AirControlPanelView!
    lazy var panelCtrlRect = CGRect(x: (contentWidth - 310) / 2, y: contentYOffset + 300, width: 310, height: 190)
    
    fileprivate var power: PowerButton!
    lazy var powerRect = CGRect(x: (contentWidth - 62) / 2, y: contentYOffset + 532, width: 62, height: 62)
    lazy var powerOffRect = CGRect(x: (contentWidth - 62) / 2, y: contentYOffset + 390, width: 62, height: 62)
    
    
    var air: ServiceAirConditioner
    init(air: ServiceAirConditioner) {
        self.air = air
        super.init(service: air.service)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let content = UIView()
        self.view.addSubview(content)
        content.translatesAutoresizingMaskIntoConstraints = false
        content.topAnchor.constraint(equalTo: self.customBar.bottomAnchor).isActive = true
        content.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
        content.widthAnchor.constraint(equalToConstant: CGFloat(contentWidth)).isActive = true
        content.heightAnchor.constraint(equalToConstant: CGFloat(contentHeight)).isActive = true
        content.layer.cornerRadius = 10
        content.backgroundColor = UIColor.white
        
        self.panelState = AirStatePanelView(frame: panelStateRect)
        content.addSubview(panelState)

        self.panelTempCtrl = AirTemperatureControlPanel(frame: panelTempCtrlRect)
        content.addSubview(panelTempCtrl)
        self.panelCtrl = AirControlPanelView(frame: panelCtrlRect)
        content.addSubview(panelCtrl)
        
        panelTempCtrl.onPercentage = { percentage in
            let temp = Double(Int(Float(30 - 16) / 0.5 * Float(percentage) / 100)) * 0.5 + 16
            if Int(temp / 0.5) % 2 == 0 {
                self.panelState.temperature = String(format: "%0.0f°", temp)
            } else {
                self.panelState.temperature = String(format: "%0.1f°", temp)
            }
            self.air.setTemperature(value: temp)
        }

        panelCtrl.onModeTapped = { index in
            self.panelCtrl.setMode(index: index)
            self.air.setMode(index: index + 1)
        }
        
        self.power = PowerButton(frame: powerRect)
        content.addSubview(power)
        power.onTapped = {
            self.air.togglePower()
        }

        self.panelCtrl.onFunctionTapped = { btn in
            switch btn {
            case .sleep, .display:
                if self.panelCtrl.functionBtns[btn.rawValue].forcused {
                    self.panelCtrl.functionBtns[btn.rawValue].forcused = false
                } else {
                    self.panelCtrl.functionBtns[btn.rawValue].forcused = true
                }
                
            case .rotation:
                var value: Int
                if self.air.rotation == .natural {
                    value = ServiceAirConditioner.RotationMode.swing.rawValue
                } else {
                    value = ServiceAirConditioner.RotationMode.natural.rawValue
                }
                self.air.setRotation(index: value)
            default:
                break
            }

        }
        self.updateService()
    }
    
    override func updateService() {
        self.customBar.subtitle = self.air.desc
        self.panelState.state = self.air.getStateDesc()
        self.panelState.temperature = self.air.getTemperature()
        self.panelState.windDesc = self.air.getWindDesc()
        self.panelCtrl.setMode(index: self.air.mode.rawValue - 1)
        let percentag = Int((self.air.temperature - 16) * 100 / 14)
        self.panelTempCtrl.setPercentage(percentag)
        if self.air.on {
            self.power.power = .on
            UIView.animate(withDuration: 0.4, delay: 0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: [], animations: {
                self.panelState.frame = self.panelStateRect
                self.power.frame = self.powerRect
            }, completion: nil)
            UIView.animate(withDuration: 0.3, delay: 0.3, usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: [], animations: {
                self.panelTempCtrl.isHidden = false
                self.panelCtrl.isHidden = false
            }, completion: nil)
        } else {
            self.power.power = .off
            UIView.animate(withDuration: 0.4, delay: 0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: [], animations: {
                self.panelState.frame = self.panelStateOffRect
                self.power.frame = self.powerOffRect
            }, completion: nil)
            UIView.animate(withDuration: 0.3, delay: 0.3, usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: [], animations: {
                self.panelTempCtrl.isHidden = true
                self.panelCtrl.isHidden = true
            }, completion: nil)
        }
        if self.air.rotation == .natural {            self.panelCtrl.functionBtns[AirControlPanelView.FunctionBtnType.rotation.rawValue].forcused = false
        } else {
            self.panelCtrl.functionBtns[AirControlPanelView.FunctionBtnType.rotation.rawValue].forcused = true
        }
    }
}



// MARK: 空调状态信息获取
extension ServiceAirConditioner {
    func getTemperature() -> String {
        if Int(self.temperature / 0.5) % 2 == 0 {
            return String(format: "%0.0f°", self.temperature)
        }
        return String(format: "%0.1f°", self.temperature)
    }
}

extension ServiceAirConditioner {
    func getStateDesc() -> String {
        if self.state == .offline {
            return "设备离线"
        }
        if self.state == .update {
            return "正在更新"
        }
        
        if self.on == false {
            return "关机状态"
        }
        
        var str = ""
        switch self.mode {
        case .auto:
            str = "自动模式" + str
        case .blowing:
            str = "送风模式"
        case .dehumidification:
            str = "除湿运行" + str
        case .cool:
            str = "制冷模式" + str
        case .heat:
            str = "制热模式" + str
        }
        return str
    }
}

extension ServiceAirConditioner {
    func getWindDesc() -> String {
        if self.rotation == .swing {
            return "上下摆风"
        } else if self.windSpeed == 0 {
            return "风速 自然风"
        }
        return String(format: "风速%d%%", self.windSpeed)
    }
}


// MARK 空调功能控制
fileprivate class AirControlPanelView: UIView {
    // MARK: 空调模式
    let modes = ["自动", "制冷", "抽湿", "制热", "送风"]
    let modeIcons = ["air-mode-auto", "air-mode-cool", "air-mode-dehumidify", "air-mode-hot", "air-mode-wind"]
    
    var onModeTapped: ((Int)->Void)?
    private var modeBtns = [AirModeButton]()
    func setMode(index: Int) {
        for (i, mode) in self.modeBtns.enumerated() {
            if index == i {
                mode.forcused = true
            } else {
                mode.forcused = false
            }
        }
    }
    
    // 空调功能
    let functions = ["风速", "睡眠", "摆风", "屏显"]
    let functionIcons = ["air-wind-speed", "air-sleep", "air-rotation", "air-oled-display"]
    
    enum FunctionBtnType: Int {
        case windSpeed = 0
        case sleep = 1
        case rotation = 2
        case display = 3
    }
    var onFunctionTapped: ((FunctionBtnType)->Void)?
    fileprivate var functionBtns = [AirModeButton]()
    func setFunction(index: FunctionBtnType, selected: Bool) {
        if selected {
            self.functionBtns[index.rawValue].forcused = true
        } else {
            self.functionBtns[index.rawValue].forcused = true
        }
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        for (index, _) in self.modes.enumerated() {
            let frame = CGRect(x: index * 64, y: 0, width: 54, height: 80)
            let btn = AirModeButton(frame: frame, name: self.modes[index], icon: self.modeIcons[index])
            btn.onTapped = {
                self.onModeTapped?(index)
            }
            btn.forcused = false
            self.addSubview(btn)
            self.modeBtns.append(btn)
        }
        
        for (index, _) in self.functions.enumerated() {
            let frame = CGRect(x: index * 64 + 32, y: 110, width: 54, height: 80)
            let btn = AirModeButton(frame: frame, name: self.functions[index], icon: self.functionIcons[index])
            btn.onTapped = {
                self.onFunctionTapped?(FunctionBtnType(rawValue: index)!)
            }
            btn.forcused = false
            self.addSubview(btn)
            self.functionBtns.append(btn)
        }
        
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

// MARK: 模式选择按键
fileprivate class AirModeButton: UIControl {
    var icon: String
    var label: String
    
    var onTapped: (()->Void)?
    var forcused: Bool = false {
        didSet {
            if self.forcused {
                self.iconImageView.image = UIImage(named: self.icon + "-selected")
            } else {
                self.iconImageView.image = UIImage(named: self.icon)
            }
        }
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)
        UIView.animate(withDuration: 0.1) {
            self.iconImageView.transform = CGAffineTransform(scaleX: 1.2, y: 1.2)
        }
    }
    
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesEnded(touches, with: event)
        self.onTapped?()
        UIView.animate(withDuration: 0.2, delay: 0.0, usingSpringWithDamping: 0.3, initialSpringVelocity: 10.0, options: [], animations: {
            self.iconImageView.transform = .identity
        })
    }
    
    private lazy var title: UILabel = {
        let label = UILabel(frame: .zero)
        let attributes: [NSAttributedString.Key : Any] = [
            NSAttributedString.Key.font: UIFont.systemFont(ofSize: 14, weight: UIFont.Weight.regular),
            NSAttributedString.Key.kern: 0.4,
            NSAttributedString.Key.foregroundColor: UIColor(hex: "525252")]
        label.textAlignment = .center
        label.attributedText = NSAttributedString(string: self.label, attributes: attributes)
        label.textAlignment = .center
        return label
    }()
    
    private lazy var iconImageView: UIImageView = {
        let view = UIImageView(frame: .zero)
        view.image = UIImage(named: "air-mode-auto-selected")
        return view
    }()
    
    init(frame: CGRect, name: String, icon: String) {
        self.label = name
        self.icon = icon
        super.init(frame: frame)
        self.addSubview(self.iconImageView)
        self.iconImageView.frame = CGRect(x: 0, y: 0, width: 54, height: 54)
        self.addSubview(self.title)
        self.title.frame = CGRect(x: 0, y: 60, width: frame.width, height: 20)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

// MARK: 状态显示面板
fileprivate class AirStatePanelView: UIView {
    var temperature: String = "" {
        didSet {
            let attributes: [NSAttributedString.Key : Any] = [
                NSAttributedString.Key.font: UIFont.systemFont(ofSize: 50, weight: UIFont.Weight.medium),
                NSAttributedString.Key.kern: 0.55,
                NSAttributedString.Key.foregroundColor: UIColor(hex: "2C2C2C"),
                ]
            self.temperatureLabel.attributedText = NSAttributedString(string: self.temperature, attributes: attributes)
        }
    }
    
    private lazy var temperatureLabel: UILabel = {
        let label = UILabel(frame: CGRect(x: 3, y: 58, width: self.frame.width, height: 60))
        label.textAlignment = .center
        return label
    }()
    
    var state: String = "" {
        didSet {
            let attributes: [NSAttributedString.Key : Any] = [
                NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16 , weight: UIFont.Weight.medium),
                NSAttributedString.Key.kern: 0.35,
                NSAttributedString.Key.foregroundColor: UIColor(hex: "2C2C2C"),
                ]
            self.stateLabel.attributedText = NSAttributedString(string: self.state, attributes: attributes)
        }
    }
    
    // 模式标签
    private lazy var stateLabel: UILabel = {
        let label = UILabel(frame: CGRect(x: 0, y: 35, width: self.frame.width, height: 16))
        label.textAlignment = .center
        return label
    }()
    
    var windDesc: String = "" {
        didSet {
            let attributes: [NSAttributedString.Key : Any] = [
                NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16, weight: UIFont.Weight.medium),
                NSAttributedString.Key.kern: 0.35,
                NSAttributedString.Key.foregroundColor: UIColor(hex: "2C2C2C"),
                ]
            self.windLabel.attributedText = NSAttributedString(string: self.windDesc, attributes: attributes)
        }
    }
    
    // 背景圆圈
    private lazy var background: UIImageView = {
        let view = UIImageView(frame: CGRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height))
        view.image = UIImage(named: "air-state-panel")
        return view
    }()
    
    private lazy var windLabel: UILabel = {
        let label = UILabel(frame: CGRect(x: 0, y: 123, width: self.frame.width, height: 16))
        label.textAlignment = .center
        return label
    }()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.backgroundColor = UIColor.gray
        self.addSubview(self.background)
        self.addSubview(self.temperatureLabel)
        self.addSubview(self.stateLabel)
        self.addSubview(self.windLabel)
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}


// MARK: 温度控制器
class AirTemperatureControlPanel: UIView {
    class CircleView: UIView {
        var angleStart: Int = -225
        var angleEnd: Int = 45 {
            didSet {
                let trackLayer = CAShapeLayer()
                let circularPath = UIBezierPath(arcCenter: center, radius: 129, startAngle: CGFloat(angleStart) / 360 * 2 * CGFloat.pi, endAngle: CGFloat(angleEnd) / 360  * 2 * CGFloat.pi, clockwise: true)
                trackLayer.path = circularPath.cgPath
                
                trackLayer.strokeColor = UIColor.lightGray.cgColor
                trackLayer.lineWidth = 30
                trackLayer.fillColor = UIColor.clear.cgColor
                trackLayer.lineCap = CAShapeLayerLineCap.round
                self.colorProgress.layer.mask = trackLayer
            }
        }
        
        lazy var colorProgress: UIView = {
            let view = UIImageView(frame: CGRect(x: 0, y: 0, width: 288, height: 288))
            view.image = UIImage(named: "air-condition-temp-set-bg")
            let trackLayer = CAShapeLayer()
            let circularPath = UIBezierPath(arcCenter: center, radius: 129, startAngle: CGFloat(angleStart) / 360 * 2 * CGFloat.pi, endAngle: CGFloat(angleEnd) / 360  * 2 * CGFloat.pi, clockwise: true)
            trackLayer.path = circularPath.cgPath
            
            trackLayer.strokeColor = UIColor.lightGray.cgColor
            trackLayer.lineWidth = 30
            trackLayer.fillColor = UIColor.clear.cgColor
            trackLayer.lineCap = CAShapeLayerLineCap.round
            view.layer.mask = trackLayer
            return view
        } ()
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            
            let trackLayer = CAShapeLayer()
            let circularPath = UIBezierPath(arcCenter: center, radius: 129, startAngle: CGFloat(angleStart) / 360 * 2 * CGFloat.pi, endAngle: CGFloat(angleEnd) / 360  * 2 * CGFloat.pi, clockwise: true)
            trackLayer.path = circularPath.cgPath
            
            trackLayer.strokeColor = UIColor(hex: "F1F1F1").cgColor
            trackLayer.lineWidth = 30
            trackLayer.fillColor = UIColor.clear.cgColor
            trackLayer.lineCap = CAShapeLayerLineCap.round
            self.layer.addSublayer(trackLayer)
            
            self.addSubview(self.colorProgress)
        }
        
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    }
    
    lazy var circle: CircleView = {
        let view = CircleView(frame: CGRect(x: 0, y: 0, width: 288, height: 288))
        return view
    } ()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.addSubview(self.circle)
        // 捕捉下滑返回手势
        let gesture = UIPanGestureRecognizer(target: nil, action: nil)
        gesture.cancelsTouchesInView = false
        self.addGestureRecognizer(gesture)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        let point = touches.first!.preciseLocation(in: self)
        self.moveTo(point: point)
        UIView.animate(withDuration: 0.1) {
            self.transform = CGAffineTransform(scaleX: 1.03, y: 1.03)
        }
    }
    
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        let point = touches.first!.preciseLocation(in: self)
        self.moveTo(point: point)
    }
    
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        let point = touches.first!.preciseLocation(in: self)
        self.moveTo(point: point)
        UIView.animate(withDuration: 0.1) {
            self.transform = .identity
        }
    }
    
    var onPercentage: ((Int) -> Void)?
    func setPercentage(_ v: Int) {
        let angle = -225 + Int(270 * v / 100)
         self.circle.angleEnd = angle
    }
    
    func moveTo(point: CGPoint) {
        let p = CGPoint(x: point.x - 144, y: 144 - point.y)
        let r = sqrt(pow(p.x, 2) + pow(p.y, 2))
        let angle = Double(atan(p.y / p.x)) * 180 / Double.pi
        print("radius = \(r) angle = \(angle.rounded(.awayFromZero))")
        
        var a: Int = Int(angle.rounded(.awayFromZero))
        if p.x < 0 && p.y < 0 {
            a = 180 + a
        } else if p.x < 0 && p.y > 0 {
            a = 180 + a
        }
        a = -a
        if a > -225 && a < 45 && r > 80 && r < 160 {
            print("p=\(p) radius = \(r) angle = \(a)")
            self.circle.angleEnd = a
            let percentage = Int(Float(a + 225) * 100 / 270)
            self.onPercentage?(percentage)
        }
    }
}








